
#include "ti_msp_dl_config.h"

/* Delay for 5ms to ensure UART TX is idle before starting transmission */
#define UART_TX_DELAY (160000)

/* Data for UART to transmit */
const uint8_t gTxPacket[] = {'M', 'S', 'P', '!'};

volatile bool gCheckUART, gDMADone;

int main(void)
{
    SYSCFG_DL_init();

    /* Optional delay to ensure UART TX is idle before starting transmission */
    delay_cycles(UART_TX_DELAY);

    /* Configure DMA source, destination and size */
    DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) &gTxPacket[0]);
    DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(&UART_0_INST->TXDATA));
    DL_DMA_setTransferSize(
        DMA, DMA_CH0_CHAN_ID, sizeof(gTxPacket) / sizeof(gTxPacket[0]));

    DL_SYSCTL_disableSleepOnExit();

    NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
    gCheckUART = false;
    gDMADone   = false;

    /*
     * The UART DMA TX interrupt is set indicating the UART is ready to
     * transmit data, so enabling the DMA will start the transfer
     */
    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);

    /* Wait in SLEEP mode until DMA interrupt is triggered */
    while (false == gDMADone) {
        __WFE();
    }

    /* Wait until all bytes have been transmitted and the TX FIFO is empty */
    while (false == gCheckUART) {
        __WFE();
    }

    DL_SYSCTL_enableSleepOnExit();
    while (1) {
        /* LED will turn ON to indicate example has completed without error */
        DL_GPIO_clearPins(GPIO_LEDS_PORT,
            (GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN));
        __WFI();
    }
}

void UART_0_INST_IRQHandler(void)
{
    switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) {
        case DL_UART_MAIN_IIDX_EOT_DONE:
            gCheckUART = true;
            break;
        case DL_UART_MAIN_IIDX_DMA_DONE_TX:
            gDMADone = true;
            break;
        default:
            break;
    }
}
